package com.hackvan2012.datastore;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;


import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Text;
import com.google.appengine.api.datastore.Transaction;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.SortDirection;
import com.hackvan2012.datastore.dao.FoodEntryObject;
import com.hackvan2012.datastore.dao.PostObject;
import com.hackvan2012.datastore.dao.TagObject;



public class AppDatastore {

 
// 		Food Entry
        private static final String FOOD_ENTRY_KIND = "Food Entry";
 
        private static final String ENTRY_ID_PROPERTY="Entry ID";
        private static final String IMG_URL_PROPERTY= "Image URL";
        private static final String TITLE_PROPERTY="Title";
        private static final String NAME_PROPERTY = "Name";
        private static final String DESCRIPTION_PROPERTY="Description";
        private static final String DATE_PROPERTY="Date";
        private static final String RESTAURANT_ID_PROPERTY="Restaurant ID";
        private static final String VOTE_COUNT_PROPERTY="Vote Count";

//		Tag
        private static final String TAG_KIND = "Tag";
        
        private static final String TAG_VALUE_PROPERTY="Value";
        private static final String TAG_COUNT_PROPERTY="Count";
        
//		Post
        private static final String POST_KIND = "Post";
        
        private static final String POST_PARENT_PROPERTY ="Parent";
        private static final String POST_DATE_PROPERTY="Date";
        private static final String POST_TEXT_PROPERTY="Text";
        
       
        private DatastoreService datastore;
        
        public AppDatastore(){
                datastore=DatastoreServiceFactory.getDatastoreService();
        }
        
        public void addFoodEntry(FoodEntryObject feo){
          Transaction txn = datastore.beginTransaction();                                
          Entity e = new Entity(FOOD_ENTRY_KIND);                                       
          e.setProperty(ENTRY_ID_PROPERTY, feo.getEntryID());     
          e.setProperty(IMG_URL_PROPERTY, feo.getImgURL());
          e.setProperty(TITLE_PROPERTY, feo.getTitle());
          e.setProperty(NAME_PROPERTY, feo.getName());
          e.setProperty(DESCRIPTION_PROPERTY, feo.getDescription());
          e.setProperty(DATE_PROPERTY, feo.getDate());
          e.setProperty(RESTAURANT_ID_PROPERTY, feo.getRestaurant());
          e.setProperty(VOTE_COUNT_PROPERTY, feo.getVote());
          datastore.put(e);                                                              
          txn.commit();      
        }
        
        public void addTag(TagObject to, Key parent){
	            Transaction txn = datastore.beginTransaction();                                
	            Entity e = new Entity(TAG_KIND, parent);                                       
	            e.setProperty(TAG_VALUE_PROPERTY,to.getTagValue());     
	            datastore.put(e);                                                              
	            txn.commit();
        }

        public void addPost(PostObject po){
            Transaction txn = datastore.beginTransaction();
            Entity e_k = queryEntry(po.getParentId()).asSingleEntity();
            if(e_k != null) {
        	Entity e = new Entity(POST_KIND, e_k.getKey());
            e.setProperty(POST_PARENT_PROPERTY, po.getParentId());
            e.setProperty(POST_DATE_PROPERTY, po.getDate());
            e.setProperty(POST_TEXT_PROPERTY, po.getText());
            datastore.put(e);
            txn.commit();
            }
        }
        
        private PreparedQuery queryTag(String tagValue){
            Query q = new Query(TAG_KIND);
            q.addFilter(TAG_VALUE_PROPERTY, FilterOperator.EQUAL, tagValue);
            return datastore.prepare(q);
          }
        
        private PreparedQuery queryEntry(String entryId){
            Query q = new Query(FOOD_ENTRY_KIND);
            q.addFilter(ENTRY_ID_PROPERTY, FilterOperator.EQUAL, entryId);
            q.addSort(VOTE_COUNT_PROPERTY,SortDirection.DESCENDING);
            return datastore.prepare(q);
          }
        
        public long castVote(String entryId){
        	PreparedQuery pq = queryEntry(entryId);
        	Entity e = pq.asSingleEntity();
        	long vote = -1;
        	if(e != null){
        		vote = (Long)e.getProperty(VOTE_COUNT_PROPERTY);
        		vote++;
        		Transaction txn = datastore.beginTransaction();  
        		e.setProperty(VOTE_COUNT_PROPERTY, vote);
        		datastore.put(e);
        		txn.commit();
        	}
        	return vote;
        }
        
        public List<FoodEntryObject> getFoodEntryListByTop(int num){
         	List<FoodEntryObject> feol = new ArrayList<FoodEntryObject>();
            Query q = new Query(FOOD_ENTRY_KIND);
            q.addSort(VOTE_COUNT_PROPERTY,SortDirection.DESCENDING);
            PreparedQuery pq = datastore.prepare(q);
            List<Entity> entityList = pq.asList(FetchOptions.Builder.withDefaults().limit(num));
            for(Entity e : entityList){
            	String id = (String)e.getProperty(ENTRY_ID_PROPERTY);
        		String url = (String)e.getProperty(IMG_URL_PROPERTY);
        		String title = (String)e.getProperty(TITLE_PROPERTY);
        		String name = (String)e.getProperty(NAME_PROPERTY);
        		String description = (String)e.getProperty(DESCRIPTION_PROPERTY);
        		Date date = (Date)e.getProperty(DATE_PROPERTY);
        		String restaurant = (String)e.getProperty(RESTAURANT_ID_PROPERTY);
        		long count = (Long)e.getProperty(VOTE_COUNT_PROPERTY);
        		FoodEntryObject feo = new FoodEntryObject(id, url, title, name, description,date,restaurant, count);
        		feol.add(feo);
            }
            return feol;
        }
        
        private List<FoodEntryObject> getFoodEntryListByTag(String tagValue){
        	Query q = new Query(TAG_KIND);
        	q.setKeysOnly();
        	q.addFilter(TAG_VALUE_PROPERTY, FilterOperator.EQUAL, tagValue);
        	PreparedQuery pq = datastore.prepare(q);
        	List<Entity> entityList = pq.asList(FetchOptions.Builder.withDefaults());
        	List<Key> keyList = new ArrayList<Key>();
        	for(Entity e : entityList){
        		Key k = e.getParent();
        		if(!keyList.contains(k))
        			keyList.add(k);
        	}
        	List<FoodEntryObject> feol = new ArrayList<FoodEntryObject>();
        	for(Key k : keyList){
        		Entity e = null;
				try {
					e = datastore.get(k);
	        		String id = (String)e.getProperty(ENTRY_ID_PROPERTY);
	        		String url = (String)e.getProperty(IMG_URL_PROPERTY);
	        		String title = (String)e.getProperty(TITLE_PROPERTY);
	        		String name = (String)e.getProperty(NAME_PROPERTY);
	        		String description = (String)e.getProperty(DESCRIPTION_PROPERTY);
	        		Date date = (Date)e.getProperty(DATE_PROPERTY);
	        		String restaurant = (String)e.getProperty(RESTAURANT_ID_PROPERTY);
	        		long count = (Long)e.getProperty(VOTE_COUNT_PROPERTY);
	        		FoodEntryObject feo = new FoodEntryObject(id, url, title, name, description,date,restaurant, count);
	        		feol.add(feo);
				} catch (EntityNotFoundException e1) {
					e1.printStackTrace();
				}
        	}
        	return feol;
        }

        
        public List<PostObject> getPosts(String entryId){
        	List<PostObject> pol = new ArrayList<PostObject>();
        	PreparedQuery pq = queryEntry(entryId);
        	List<Entity> entityList = pq.asList(FetchOptions.Builder.withDefaults());
            for(Iterator<Entity> i = entityList.iterator(); i.hasNext();){
                    Entity e = i.next();
                    String postParent = (String)e.getProperty(POST_PARENT_PROPERTY);
                    Date postDate = (Date)e.getProperty(POST_DATE_PROPERTY);
                    Text postText = (Text)e.getProperty(POST_TEXT_PROPERTY);
                  	pol.add(new PostObject(postParent,postDate,postText));
            }
            return pol;
        }
        
        public FoodEntryObject getFoodEntry(String entryId){
        	PreparedQuery pq = queryEntry(entryId);
        	Entity e = pq.asSingleEntity();
        	if(e != null){
        		String id = (String)e.getProperty(ENTRY_ID_PROPERTY);
        		String url = (String)e.getProperty(IMG_URL_PROPERTY);
        		String title = (String)e.getProperty(TITLE_PROPERTY);
        		String name = (String)e.getProperty(NAME_PROPERTY);
        		String description = (String)e.getProperty(DESCRIPTION_PROPERTY);
        		Date date = (Date)e.getProperty(DATE_PROPERTY);
        		String restaurant = (String)e.getProperty(RESTAURANT_ID_PROPERTY);
        		long count = (Long)e.getProperty(VOTE_COUNT_PROPERTY);
        		FoodEntryObject feo = new FoodEntryObject(id, url, title, name, description,date,restaurant, count);
        		return feo;
        	}
        	return null;
        }
        
        
        
        

//        public boolean checkAccountExist(String email){
//                PreparedQuery query=queryAccount(email);
//                if(query.countEntities(FetchOptions.Builder.withDefaults())==0){
//                        return false;
//                }
//                return true;
//                
//        }
//        
//        public boolean activateAccount(String email, String authKey){
//                PreparedQuery pq = queryAccount(email);
//                Entity e = pq.asSingleEntity();
//                if (e == null)
//                        return false;
//                if(!e.getProperty(AUTHENTICATION_KEY_PROPERTY).equals(authKey))
//                        return false;
//                if(e.getProperty(ACTIVATED_PROPERTY).equals(true))
//                        return false;
//                Transaction txn = datastore.beginTransaction();
//                e.setProperty(ACTIVATED_PROPERTY, true);
//                datastore.put(e);
//                txn.commit();
//                return true;
//        }
//        
//        private PreparedQuery queryAccount(String email){
//                Query q = new Query(ACCOUNT_KIND);
//                q.addFilter(ACCOUNT_ID_PROPERTY, FilterOperator.EQUAL, email);
//                return datastore.prepare(q);
//        }
//        
//        public AccountObject getAccountObject(String accountId) {
//                if(accountId == null)
//                        return null;
//                Query q = new Query(ACCOUNT_KIND);
//                q.addFilter(ACCOUNT_ID_PROPERTY, Query.FilterOperator.EQUAL, accountId);
//                Entity qe = datastore.prepare(q).asSingleEntity();
//                if(qe == null)
//                        return null;
//                String password = (String) qe.getProperty(PASSWORD_PROPERTY);
//                boolean active = (Boolean) qe.getProperty(ACTIVATED_PROPERTY);
//                String authKey=(String) qe.getProperty(AUTHENTICATION_KEY_PROPERTY);
//                long notifyConfig = (Long)qe.getProperty(PREFERENCE_NOTIFY_CONFIG_PROPERTY);
//                String phoneNumber = (String)qe.getProperty(PREFERENCE_PHONE_NUMBER_PROPERTY);
//                CARRIER carrier = CARRIER.get((String)qe.getProperty(PREFERENCE_CARRIER_PROPERTY));
//                return new AccountObject(accountId,password,active,authKey, notifyConfig, phoneNumber, carrier);
//        }
//        
//        public boolean updateAccountObject(AccountObject lao){
//                Query q = new Query(ACCOUNT_KIND);
//                q.addFilter(ACCOUNT_ID_PROPERTY, Query.FilterOperator.EQUAL, lao.getEmail());
//                Entity qe = datastore.prepare(q).asSingleEntity();
//                if(qe == null)
//                        return false;
//                Transaction txn = datastore.beginTransaction();   
//                qe.setProperty(PASSWORD_PROPERTY, lao.getPassword());
//                qe.setProperty(AUTHENTICATION_KEY_PROPERTY, lao.getAuthkey());
//                qe.setProperty(PREFERENCE_NOTIFY_CONFIG_PROPERTY, lao.getNotifyConfig());
//                qe.setProperty(PREFERENCE_PHONE_NUMBER_PROPERTY, lao.getPhoneNumber());
//                qe.setProperty(PREFERENCE_CARRIER_PROPERTY, lao.getCarrier().getGateway());
//                datastore.put(qe);
//                txn.commit();
//                return true;
//        }
//        
//        //Bi-directional subscription adding
//        public boolean addSubscription(String from, String to){
//                Query q_from = new Query(ACCOUNT_KIND);
//                q_from.addFilter(ACCOUNT_ID_PROPERTY, FilterOperator.EQUAL, from);
//                q_from.setKeysOnly();
//                PreparedQuery pq_from = datastore.prepare(q_from);
//                Entity e_from = pq_from.asSingleEntity();
//                
//                Query q_to = new Query(ACCOUNT_KIND);
//                q_to.addFilter(ACCOUNT_ID_PROPERTY, FilterOperator.EQUAL, to);
//                q_to.setKeysOnly();
//                PreparedQuery pq_to = datastore.prepare(q_to);
//                Entity e_to = pq_to.asSingleEntity();
//                
//                if(e_from == null || e_to == null)
//                        return false;
//                Key k_from = e_from.getKey();
//                Key k_to = e_to.getKey();
//                if(checkSubscriptionExists(k_from, from, k_to, to))
//                        return false;
//                Transaction txn = datastore.beginTransaction(); 
//                Entity sub_from = new Entity(SUBSCRIPTION_KIND, k_from);
//                sub_from.setProperty(SUBSCRIPTION_EMAIL_PROPERTY, to);
//                //When first add, set a pending request
//                sub_from.setProperty(SUBSCRIPTION_STATUS_PROPERTY, "Waiting");
//                datastore.put(sub_from);
//                Entity sub_to = new Entity(SUBSCRIPTION_KIND, k_to);
//                sub_to.setProperty(SUBSCRIPTION_EMAIL_PROPERTY, from);
//                sub_to.setProperty(SUBSCRIPTION_STATUS_PROPERTY, "Pending");
//                datastore.put(sub_to);
//                txn.commit();
//                return true;
//        }
//        
//        //Bidirectional email check
//        public boolean checkSubscriptionExists(String from, String to){
//                Query q_from = new Query(ACCOUNT_KIND);
//                q_from.addFilter(ACCOUNT_ID_PROPERTY, FilterOperator.EQUAL, from);
//                q_from.setKeysOnly();
//                PreparedQuery pq_from = datastore.prepare(q_from);
//                Entity e_from = pq_from.asSingleEntity();
//                Key from_key = e_from.getKey();
//                
//                Query q_to = new Query(ACCOUNT_KIND);
//                q_to.addFilter(ACCOUNT_ID_PROPERTY, FilterOperator.EQUAL, to);
//                q_to.setKeysOnly();
//                PreparedQuery pq_to = datastore.prepare(q_to);
//                Entity e_to = pq_to.asSingleEntity();
//                Key to_key = e_to.getKey();
//                
//                Query sub_from = new Query(SUBSCRIPTION_KIND);
//                sub_from.setAncestor(from_key);
//                sub_from.addFilter(SUBSCRIPTION_EMAIL_PROPERTY, FilterOperator.EQUAL, to);
//                sub_from.addFilter(SUBSCRIPTION_STATUS_PROPERTY, FilterOperator.EQUAL, SUBSCRIPTION_STATUS_ACTIVE);
//                sub_from.setKeysOnly();
//                PreparedQuery sub_pq_from = datastore.prepare(sub_from);
//                
//                Query sub_to = new Query(SUBSCRIPTION_KIND);
//                sub_to.setAncestor(to_key);
//                sub_to.addFilter(SUBSCRIPTION_EMAIL_PROPERTY, FilterOperator.EQUAL, from);
//                sub_from.addFilter(SUBSCRIPTION_STATUS_PROPERTY, FilterOperator.EQUAL, SUBSCRIPTION_STATUS_ACTIVE);
//                sub_to.setKeysOnly();
//                PreparedQuery sub_pq_to = datastore.prepare(sub_to);
//                
//                if(sub_pq_from.asSingleEntity() != null || sub_pq_to.asSingleEntity() != null )
//                        return true;
//                return false;
//                
//        }
//        
//        //Bidirectional check
//        private boolean checkSubscriptionExists(Key from_key, String from, Key to_key, String to){
//                Query q_from = new Query(SUBSCRIPTION_KIND);
//                q_from.setAncestor(from_key);
//                q_from.addFilter(SUBSCRIPTION_EMAIL_PROPERTY, FilterOperator.EQUAL, to);
//                q_from.setKeysOnly();
//                PreparedQuery pq_from = datastore.prepare(q_from);
//                
//                Query q_to = new Query(SUBSCRIPTION_KIND);
//                q_to.setAncestor(to_key);
//                q_to.addFilter(SUBSCRIPTION_EMAIL_PROPERTY, FilterOperator.EQUAL, from);
//                q_to.setKeysOnly();
//                PreparedQuery pq_to = datastore.prepare(q_to);
//                if(pq_from.asSingleEntity() != null || pq_to.asSingleEntity() != null )
//                        return true;
//                return false;
//        }
//        
//        //Bidirectional subscription activation
//        public boolean activateSubscription(String from, String to) {
//                Query q_from = new Query(ACCOUNT_KIND);
//                q_from.setKeysOnly();
//                q_from.addFilter(ACCOUNT_ID_PROPERTY, FilterOperator.EQUAL, from);
//                PreparedQuery from_key = datastore.prepare(q_from);
//                Entity e_from = from_key.asSingleEntity();
//                if(e_from == null)
//                        return false;
//                Key key_from = e_from.getKey();
//                
//                Query q_to = new Query(ACCOUNT_KIND);
//                q_to.setKeysOnly();
//                q_to.addFilter(ACCOUNT_ID_PROPERTY, FilterOperator.EQUAL, to);
//                PreparedQuery to_key = datastore.prepare(q_to);
//                Entity e_to = to_key.asSingleEntity();
//                if(e_to == null)
//                        return false;
//                Key key_to = e_to.getKey();
//                
//                
//                Query s_to = new Query(SUBSCRIPTION_KIND);
//                s_to.setAncestor(key_to);
//                s_to.addFilter(SUBSCRIPTION_EMAIL_PROPERTY, FilterOperator.EQUAL, from);
//                PreparedQuery pq_to = datastore.prepare(s_to);
//                Entity sub_to = pq_to.asSingleEntity();
//                if(sub_to == null || !sub_to.getProperty(SUBSCRIPTION_STATUS_PROPERTY).equals(SUBSCRIPTION_STATUS_WAITING))
//                        return false;
//                sub_to.setProperty(SUBSCRIPTION_STATUS_PROPERTY, SUBSCRIPTION_STATUS_ACTIVE);
//                
//                Query s_from = new Query(SUBSCRIPTION_KIND);
//                s_from.setAncestor(key_from);
//                s_from.addFilter(SUBSCRIPTION_EMAIL_PROPERTY, FilterOperator.EQUAL, to);
//                PreparedQuery pq_from = datastore.prepare(s_from);
//                Entity sub_from = pq_from.asSingleEntity();
//                if(sub_from == null || !sub_from.getProperty(SUBSCRIPTION_STATUS_PROPERTY).equals(SUBSCRIPTION_STATUS_PENDING))
//                        return false;
//                sub_from.setProperty(SUBSCRIPTION_STATUS_PROPERTY, SUBSCRIPTION_STATUS_ACTIVE);
//                Transaction txn = datastore.beginTransaction();
//                datastore.put(sub_to);
//                datastore.put(sub_from);
//                txn.commit();
//                return true;
//        }
//        
//        public boolean declineSubscription(String from, String to){
//                Query q_from = new Query(ACCOUNT_KIND);
//                q_from.setKeysOnly();
//                q_from.addFilter(ACCOUNT_ID_PROPERTY, FilterOperator.EQUAL, from);
//                PreparedQuery from_key = datastore.prepare(q_from);
//                Entity e_from = from_key.asSingleEntity();
//                if(e_from == null)
//                        return false;
//                Key key_from = e_from.getKey();
//                
//                Query q_to = new Query(ACCOUNT_KIND);
//                q_to.setKeysOnly();
//                q_to.addFilter(ACCOUNT_ID_PROPERTY, FilterOperator.EQUAL, to);
//                PreparedQuery to_key = datastore.prepare(q_to);
//                Entity e_to = to_key.asSingleEntity();
//                if(e_to == null)
//                        return false;
//                Key key_to = e_to.getKey();
//                
//                
//                Query s_to = new Query(SUBSCRIPTION_KIND);
//                s_to.setAncestor(key_to);
//                s_to.addFilter(SUBSCRIPTION_EMAIL_PROPERTY, FilterOperator.EQUAL, from);
//                s_to.setKeysOnly();
//                PreparedQuery pq_to = datastore.prepare(s_to);
//                Entity sub_to = pq_to.asSingleEntity();
//                if(sub_to == null || !sub_to.getProperty(SUBSCRIPTION_STATUS_PROPERTY).equals(SUBSCRIPTION_STATUS_WAITING))
//                        return false;
//                
//                Query s_from = new Query(SUBSCRIPTION_KIND);
//                s_from.setAncestor(key_from);
//                s_from.addFilter(SUBSCRIPTION_EMAIL_PROPERTY, FilterOperator.EQUAL, to);
//                s_from.setKeysOnly();
//                PreparedQuery pq_from = datastore.prepare(s_from);
//                Entity sub_from = pq_from.asSingleEntity();
//                if(sub_from == null || !sub_from.getProperty(SUBSCRIPTION_STATUS_PROPERTY).equals(SUBSCRIPTION_STATUS_PENDING))
//                        return false;
//                Transaction txn = datastore.beginTransaction();
//                datastore.delete(sub_to.getKey());
//                datastore.delete(sub_from.getKey());
//                txn.commit();
//                return true;
//        }
//        
//        public List<SubscriptionInformationObject> getSubscriptions(String user, String type){
//                List<SubscriptionInformationObject> subl = new ArrayList<SubscriptionInformationObject>();
//                Query key_query = new Query(ACCOUNT_KIND);
//                key_query.setKeysOnly();
//                key_query.addFilter(ACCOUNT_ID_PROPERTY, FilterOperator.EQUAL, user);
//                PreparedQuery pq_key = datastore.prepare(key_query);
//                Entity e_user = pq_key.asSingleEntity();
//                if(e_user == null)
//                        return subl;
//                Key key = e_user.getKey();
//                Query q_sub = new Query(SUBSCRIPTION_KIND);
//                q_sub.setAncestor(key);
//                if(type.equalsIgnoreCase(SUBSCRIPTION_STATUS_WAITING) || type.equalsIgnoreCase(SUBSCRIPTION_STATUS_PENDING)) {
//                        q_sub.addFilter(SUBSCRIPTION_STATUS_PROPERTY, FilterOperator.NOT_EQUAL, SUBSCRIPTION_STATUS_ACTIVE);
//                        q_sub.addSort(SUBSCRIPTION_STATUS_PROPERTY, SortDirection.DESCENDING);
//                }
//                else if (type.equalsIgnoreCase(SUBSCRIPTION_STATUS_ACTIVE))
//                        q_sub.addFilter(SUBSCRIPTION_STATUS_PROPERTY, FilterOperator.EQUAL, SUBSCRIPTION_STATUS_ACTIVE);
//                PreparedQuery pq = datastore.prepare(q_sub);
//                List<Entity> entityList = pq.asList(FetchOptions.Builder.withDefaults());
//                for(Iterator<Entity> i = entityList.iterator(); i.hasNext();){
//                        Entity e = i.next();
//                        String email = (String) e.getProperty(SUBSCRIPTION_EMAIL_PROPERTY);
//                        String status = (String) e.getProperty(SUBSCRIPTION_STATUS_PROPERTY);
//                        subl.add(new SubscriptionInformationObject(email,status));
//                }
//                return subl;
//        }
//        
//        public boolean publishFeed(String email, String message){
//                Query key_query = new Query(ACCOUNT_KIND);
//                key_query.setKeysOnly();
//                key_query.addFilter(ACCOUNT_ID_PROPERTY, FilterOperator.EQUAL, email);
//                PreparedQuery pq_key = datastore.prepare(key_query);
//                Entity e_from = pq_key.asSingleEntity();
//                if(e_from == null)
//                        return false;
//                Key key = e_from.getKey();
//                Query q_sub = new Query(SUBSCRIPTION_KIND);
//                q_sub.setAncestor(key);
//                PreparedQuery pq = datastore.prepare(q_sub);
//                List<Entity> entityList = pq.asList(FetchOptions.Builder.withDefaults());
//                for(Iterator<Entity> i = entityList.iterator(); i.hasNext();){
//                        Entity e = i.next();
//                        String to_email = (String) e.getProperty(SUBSCRIPTION_EMAIL_PROPERTY);
//                        addFeed(to_email,email,message);
//                }
//                return true;
//        }
//        
//        //add feed
//        private boolean addFeed(String subscriber, String sender, String message){
//                Query key_query = new Query(ACCOUNT_KIND);
//                key_query.setKeysOnly();
//                key_query.addFilter(ACCOUNT_ID_PROPERTY, FilterOperator.EQUAL, subscriber);
//                PreparedQuery pq_key = datastore.prepare(key_query);
//                Entity e_subscriber = pq_key.asSingleEntity();
//                if(e_subscriber == null)
//                        return false;
//                Key sub_key = e_subscriber.getKey();
//                Query q_sub_sender = new Query(SUBSCRIPTION_KIND);
//                q_sub_sender.setAncestor(sub_key);
//                q_sub_sender.setKeysOnly();
//                q_sub_sender.addFilter(SUBSCRIPTION_EMAIL_PROPERTY, FilterOperator.EQUAL, sender);
//                q_sub_sender.addFilter(SUBSCRIPTION_STATUS_PROPERTY, FilterOperator.EQUAL, "Active");
//                PreparedQuery pq_sender = datastore.prepare(q_sub_sender);
//                Entity sender_entity = pq_sender.asSingleEntity();
//                if(sender_entity == null)
//                        return false;
//                Key sender_key = sender_entity.getKey();
//                Transaction txn = datastore.beginTransaction();
//                Entity sender_feed = new Entity(FEED_KIND, sender_key);
//                sender_feed.setProperty(FEED_READ_STATUS_PROPERTY, false);
//                sender_feed.setProperty(FEED_MESSAGE_PROPERTY, new Text(message));
//                sender_feed.setProperty(FEED_TIMESTAMP_PROPERTY, new Date());
//                datastore.put(sender_feed);
//                txn.commit();
//                return true;
//        }
//        
//        public List<SubscriptionFeedObject> readFeeds(String email, boolean setRead, boolean getUnreadOnly){
//                List<SubscriptionFeedObject> feeds = new ArrayList<SubscriptionFeedObject>();
//                Query q = new Query(ACCOUNT_KIND);
//                q.setKeysOnly();
//                q.addFilter(ACCOUNT_ID_PROPERTY, FilterOperator.EQUAL, email);
//                PreparedQuery pq = datastore.prepare(q);
//                Entity e = pq.asSingleEntity();
//                if(e == null) {
//                        return feeds;
//                }
//                Key k = e.getKey();
//                Query q_feed = new Query(FEED_KIND);
//                q_feed.setAncestor(k);
//                q_feed.addSort(FEED_TIMESTAMP_PROPERTY,SortDirection.DESCENDING);
//                if(getUnreadOnly)
//                        q_feed.addFilter(FEED_READ_STATUS_PROPERTY, FilterOperator.EQUAL, false);
//                PreparedQuery pq_feed = datastore.prepare(q_feed);
//                List<Entity> entityList = pq_feed.asList(FetchOptions.Builder.withDefaults());
//                for(Iterator<Entity> i = entityList.iterator(); i.hasNext();) {
//                        Entity e_feed = i.next();
//                        Text feed_message_t = (Text)e_feed.getProperty(FEED_MESSAGE_PROPERTY);
//                        String feed_message = feed_message_t.getValue();
//                        boolean feed_read = (Boolean)e_feed.getProperty(FEED_READ_STATUS_PROPERTY);
//                        Date feed_timestamp = (Date)e_feed.getProperty(FEED_TIMESTAMP_PROPERTY);
//                        feeds.add(new SubscriptionFeedObject(feed_read, feed_message, feed_timestamp));
//                        if(setRead) {
//                                e_feed.setProperty(FEED_READ_STATUS_PROPERTY, true);
//                                datastore.put(e_feed);
//                        }
//                                
//                }
//                return feeds;
//                
//        }
//        
//        public boolean addWorklistItem(String user, WorklistItemObject wio){
//                if (!checkWorklistItemExists(user, wio)) {
//                        Query q_user = new Query(ACCOUNT_KIND);
//                        q_user.setKeysOnly();
//                        q_user.addFilter(ACCOUNT_ID_PROPERTY, FilterOperator.EQUAL, user);
//                        PreparedQuery pq = datastore.prepare(q_user);
//                        Entity e_user = pq.asSingleEntity();
//                        if (e_user == null)
//                                return false;
//                        Key k = e_user.getKey();
//                        Transaction txn = datastore.beginTransaction();
//                        Entity e_wli = new Entity(WORKLIST_ITEM_KIND, k);
//                        e_wli.setProperty(WORKLIST_ITEM_DEPT_PROPERTY, wio.getDeptId());
//                        e_wli.setProperty(WORKLIST_ITEM_COURSE_PROPERTY, wio.getCourseId());
//                        e_wli.setProperty(WORKLIST_ITEM_SECTION_PROPERTY, wio.getSectionId());
//                        if(spiderDatastore.querySectionFromId( wio.getDeptId(), wio.getCourseId(),wio.getSectionId()) == null)
//                                return false;
//                        datastore.put(e_wli);
//                        txn.commit();
//                } else
//                        return false;
//                return true;
//        }
//        
//        public boolean checkWorklistItemExists(String user, WorklistItemObject wio){
//                Query q_user = new Query(ACCOUNT_KIND);
//                q_user.setKeysOnly();
//                q_user.addFilter(ACCOUNT_ID_PROPERTY, FilterOperator.EQUAL, user);
//                PreparedQuery pq = datastore.prepare(q_user);
//                Entity e_user = pq.asSingleEntity();
//                if(e_user == null)
//                        return false;
//                Key k = e_user.getKey();
//                Query q_wio = new Query(WORKLIST_ITEM_KIND);
//                q_wio.setAncestor(k);
//                q_wio.addFilter(WORKLIST_ITEM_DEPT_PROPERTY, FilterOperator.EQUAL, wio.getDeptId());
//                q_wio.addFilter(WORKLIST_ITEM_COURSE_PROPERTY, FilterOperator.EQUAL, wio.getCourseId());
//                q_wio.addFilter(WORKLIST_ITEM_SECTION_PROPERTY, FilterOperator.EQUAL, wio.getSectionId());
//                q_wio.setKeysOnly();
//                PreparedQuery pq_wio = datastore.prepare(q_wio);
//                if(pq_wio.asSingleEntity() == null)
//                        return false;
//                return true;
//        }
//        
//        public boolean deleteWorklistItem(String user, WorklistItemObject wio){
//                        Query q_user = new Query(ACCOUNT_KIND);
//                        q_user.setKeysOnly();
//                        q_user.addFilter(ACCOUNT_ID_PROPERTY, FilterOperator.EQUAL, user);
//                        PreparedQuery pq = datastore.prepare(q_user);
//                        Entity e_user = pq.asSingleEntity();
//                        if (e_user == null)
//                                return false;
//                        Key k = e_user.getKey();
//                        Query q_wio = new Query(WORKLIST_ITEM_KIND);
//                        q_wio.setAncestor(k);
//                        q_wio.setKeysOnly();
//                        q_wio.addFilter(WORKLIST_ITEM_DEPT_PROPERTY, FilterOperator.EQUAL, wio.getDeptId());
//                        q_wio.addFilter(WORKLIST_ITEM_COURSE_PROPERTY, FilterOperator.EQUAL, wio.getCourseId());
//                        q_wio.addFilter(WORKLIST_ITEM_SECTION_PROPERTY, FilterOperator.EQUAL, wio.getSectionId());
//                        PreparedQuery pq_wio = datastore.prepare(q_wio);
//                        if(pq_wio.asSingleEntity() == null)
//                                return false;
//                        Transaction txn = datastore.beginTransaction();
//                        datastore.delete(pq_wio.asSingleEntity().getKey());
//                        txn.commit();
//                        return true;
//        }
//        
//        public List<SectionInformationObject> getWorklistAsSIO(String user){
//                List<SectionInformationObject> siol = new ArrayList<SectionInformationObject>();
//                Query q_user = new Query(ACCOUNT_KIND);
//                q_user.setKeysOnly();
//                q_user.addFilter(ACCOUNT_ID_PROPERTY, FilterOperator.EQUAL, user);
//                PreparedQuery pq = datastore.prepare(q_user);
//                Entity e_user = pq.asSingleEntity();
//                if(e_user == null)
//                        return siol;
//                Key k = e_user.getKey();
//                Query q = new Query(WORKLIST_ITEM_KIND);
//                q.setAncestor(k);
//                PreparedQuery pq_wl = datastore.prepare(q);
//                List<Entity> el = pq_wl.asList(FetchOptions.Builder.withDefaults());
//                for(Iterator<Entity> i = el.iterator(); i.hasNext(); ) {
//                        Entity e = i.next();
//                        String dept = (String) e.getProperty(WORKLIST_ITEM_DEPT_PROPERTY);
//                        String course = (String)e.getProperty(WORKLIST_ITEM_COURSE_PROPERTY);
//                        String section = (String)e.getProperty(WORKLIST_ITEM_SECTION_PROPERTY);
//                        SectionInformationObject sio = spiderDatastore.querySectionFromId(dept, course, section);
//                        siol.add(sio);
//                }
//                
//                return siol;
//        }
//        
//        public List<WorklistItemObject> getWorklistAsWIO(String user){
//                List<WorklistItemObject> wiol = new ArrayList<WorklistItemObject>();
//                Query q_user = new Query(ACCOUNT_KIND);
//                q_user.setKeysOnly();
//                q_user.addFilter(ACCOUNT_ID_PROPERTY, FilterOperator.EQUAL, user);
//                PreparedQuery pq = datastore.prepare(q_user);
//                Entity e_user = pq.asSingleEntity();
//                if(e_user == null)
//                        return wiol;
//                Key k = e_user.getKey();
//                Query q = new Query(WORKLIST_ITEM_KIND);
//                q.setAncestor(k);
//                PreparedQuery pq_wl = datastore.prepare(q);
//                List<Entity> el = pq_wl.asList(FetchOptions.Builder.withDefaults());
//                for(Iterator<Entity> i = el.iterator(); i.hasNext(); ) {
//                        Entity e = i.next();
//                        String dept = (String) e.getProperty(WORKLIST_ITEM_DEPT_PROPERTY);
//                        String course = (String)e.getProperty(WORKLIST_ITEM_COURSE_PROPERTY);
//                        String section = (String)e.getProperty(WORKLIST_ITEM_SECTION_PROPERTY);
//                        WorklistItemObject wio = new WorklistItemObject(dept,course,section);
//                        wiol.add(wio);
//                }
//                return wiol;
//        }
        
}